import React from 'react';
import PropTypes from 'prop-types';
import { Form, DatePicker, Input, Select, Checkbox } from 'antd';
import '../common/sysext';

export class RawInnerForm extends React.Component {

    static propTypes = {
        form: PropTypes.object,
        items: PropTypes.array,
        formProps: PropTypes.object,
        itemProps: PropTypes.object
    }

    render() {
        const { getFieldDecorator } = this.props.form;
        return <Form {...this.props.formProps}>
            {(this.props.items || []).map((item, index) => {
                let { colon, extra, hasFeedback, help, label, labelCol, validateStatus, wrapperCol } = item;
                let { id, getValueFromEvent, initialValue, normalize, rules, trigger, validateFirst, validateTrigger, valuePropName } = item;
                let name = item.name;
                return <Form.Item key={id || name || 'item' + index}
                    {...this.props.itemProps}
                    {...{ colon, extra, hasFeedback, help, label, labelCol, validateStatus, wrapperCol }.defaultFilter()}>
                    {
                        name ? getFieldDecorator(name,
                            {
                                id, getValueFromEvent, initialValue, normalize, rules, trigger, validateFirst,
                                validateTrigger, valuePropName
                            }.defaultFilter())(
                                this.generateContent(item)
                            )
                            : this.generateContent(item)
                    }
                </Form.Item>;
            })}
        </Form>;
    }

   
    generateContent(item) {
        if (item.content) {
            return item.content;
        }
        if (item.component) {
            return <item.component {...item.itemProps} />;
        }
        switch (item.type) {
            case 'boolean': return <Checkbox {...item.itemProps} />;
            case 'date': return <DatePicker {...item.itemProps} />;
            case 'enum': return <Select {...item.itemProps} />;
            default: return <Input {...item.itemProps} />;
        }
    }
}

export default class AutoForm extends React.Component {
    static propTypes = {
        items: PropTypes.array,
        options: PropTypes.object,
        itemProps: PropTypes.object,
        onChange: PropTypes.func,
        value: PropTypes.object,
        mapValuesToFields: PropTypes.func,
        mapFieldsToValues: PropTypes.func,
    }

    state = {}

    getForm() {
        return this.form;
    }

    componentDidMount() {
        let InnerForm = Form.create(Object.assign({}, this.props.options))(RawInnerForm);
        this.setState({ InnerForm });
    }

    mapFieldsToValues(fields) {
        return (this.props.mapFieldsToValues || (e => e))(fields);
    }

    mapValuesToFields(values) {
        return (this.props.mapValuesToFields || (e => e))(values);
    }

    render() {
        let props = Object.assign({}, this.props);
        delete props.items;
        delete props.options;
        delete props.itemProps;
        return this.state.InnerForm ? <this.state.InnerForm 
            items={this.props.items} 
            formProps={props}
            itemProps={this.props.itemProps}
            ref={form => this.form = form}
        /> : <div style={{ display: 'none' }} />;
    }

} 